package com.yuncheng.spcyApi.busService;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.spcyApi.constant.other.PxSjConstant;
import com.yuncheng.spcyApi.entity.SpcyWjWjtm;
import com.yuncheng.spcyApi.mapper.SpcyWjWjjbxxMapper;
import com.yuncheng.spcyApi.service.ISpcyWjWjtmService;
import com.yuncheng.spcyApi.utils.StringPatternUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 问卷统计
 */
@Component(value = "wjStatService")
public class WjStatService {

    private static final Logger log = LoggerFactory.getLogger(WjStatService.class);

    @Resource
    private SpcyWjWjjbxxMapper spcyWjWjjbxxMapper;

    @Resource
    private ISpcyWjWjtmService spcyWjWjtmService;

    /**
     * 问卷填写-题目选项统计
     * @param fwjjbxxid
     * @return
     */
    public List<Map> queryWjStat(String fwjjbxxid){

        // 总提交数
        Integer total = spcyWjWjjbxxMapper.findWjSubmitCount(fwjjbxxid);

        // 问卷大标题
        List<String> wjDbtList = spcyWjWjjbxxMapper.findWjDbtList(fwjjbxxid);
        if (CollectionUtil.isEmpty(wjDbtList)){
            wjDbtList.add("test");
        }

        // 所有题目
        List<SpcyWjWjtm> orTmList = spcyWjWjtmService.list(new LambdaQueryWrapper<SpcyWjWjtm>()
                .eq(SpcyWjWjtm::getFwjjbxxid, fwjjbxxid)
                .orderByAsc(SpcyWjWjtm::getFxh));

/*        // 所有题目
        List<SpcyWjWjtm> tmList = spcyWjWjtmService.list(new LambdaQueryWrapper<SpcyWjWjtm>()
                .eq(SpcyWjWjtm::getFwjjbxxid, fwjjbxxid)
                .orderByAsc(SpcyWjWjtm::getFxh));*/

        List<Map> resultList = new ArrayList<>();

        for (String wjdbt : wjDbtList) {

            List<SpcyWjWjtm> tmList = null;
            if (!wjdbt.equals("test")) {
                tmList = orTmList.stream()
                        .filter(f -> StringUtils.isNotBlank(f.getFwjtmdbt()) && f.getFwjtmdbt().equals(wjdbt))
                        .collect(Collectors.toList());
            }else {
                tmList = spcyWjWjtmService.list(new LambdaQueryWrapper<SpcyWjWjtm>()
                        .eq(SpcyWjWjtm::getFwjjbxxid, fwjjbxxid)
                        .orderByAsc(SpcyWjWjtm::getFxh));
            }

            if (CollectionUtil.isEmpty(tmList)){
                continue;
            }

            Map tmMap = null;
            for (SpcyWjWjtm tm : tmList) {
                tmMap = new HashMap();

                tmMap.put("tm", tm.getFwjtm());

                /*List<SpcyWjWjtmxx> allTmxxList = spcyWjWjtmxxService.list(new LambdaQueryWrapper<SpcyWjWjtmxx>()
                        .eq(SpcyWjWjtmxx::getFwjtmid, tm.getId())
                        .orderByAsc(SpcyWjWjtmxx::getFxh));*/
                List<String> wjtmxxList = spcyWjWjjbxxMapper.findWjtmxxList(tm.getId());

                // 对应题目-所以选中的选项
                List<String> selectedTmxxList = spcyWjWjjbxxMapper.findSelectedOption(fwjjbxxid, tm.getFwjtm(), PxSjConstant.WJTM_XX_SFXZ_YES);

                List<Map> tmxxMapList = new ArrayList<>(wjtmxxList.size());
                Map tmxxMap = null;
                for (String xx : wjtmxxList) {
                    tmxxMap = new HashMap();
                    int size = 0;
                    tmxxMap.put("tmxx", xx);

                    if (CollectionUtil.isNotEmpty(selectedTmxxList)) {
                        size = selectedTmxxList.stream()
                                .filter(str -> StringUtils.isNotBlank(str) && str.equals(xx))
                                .collect(Collectors.toList())
                                .size();
                    }
                    tmxxMap.put("count", size);
                    tmxxMap.put("countBl", StringPatternUtils.CalculatePpercentage(size, total) + "%");
                    tmxxMapList.add(tmxxMap);
                }

                // 题目是否配置填写-意见
                if (StringUtils.isNotBlank(tm.getFsftxyjjy()) && tm.getFsftxyjjy().equals("是")){
                    StringBuffer tmyj = new StringBuffer();
                    tmxxMap = new HashMap();

                    List<String> wjtmTxyjList = spcyWjWjjbxxMapper.findWjtmTxyj(fwjjbxxid, tm.getFwjtm());
                    int order = 0;
                    for (String yj : wjtmTxyjList){
                        if (StringUtils.isBlank(yj)){
                            continue;
                        }
                        if (!StringPatternUtils.verifryIsEmptyStringBuffer(tmyj)){
                            tmyj.append("\n");
                        }
                        tmyj.append( (order + 1) + ". ").append(yj);
                        order++;
                    }

                    tmxxMap.put("tmxx", "(其他/意见)：\n" + tmyj.toString());
                    tmxxMap.put("count", order);
                    tmxxMap.put("countBl", StringPatternUtils.CalculatePpercentage(order, total) + "%");

                    tmxxMapList.add(tmxxMap);
                }

                tmMap.put("tmxxList", tmxxMapList);
                resultList.add(tmMap);
            }
        }

        return resultList;
    }

    private static class WjtmStatBo{
        // 题目
        String tm;

        // 题目选项
        String tmxx;

        // 题目意见
        String tmyj;

        // 题目选择数量
        Integer tmxxSize;

        // 比率
        String tmxxBl;

        public String getTm() {
            return tm;
        }

        public void setTm(String tm) {
            this.tm = tm;
        }

        public String getTmxx() {
            return tmxx;
        }

        public void setTmxx(String tmxx) {
            this.tmxx = tmxx;
        }

        public String getTmyj() {
            return tmyj;
        }

        public void setTmyj(String tmyj) {
            this.tmyj = tmyj;
        }

        public Integer getTmxxSize() {
            return tmxxSize;
        }

        public void setTmxxSize(Integer tmxxSize) {
            this.tmxxSize = tmxxSize;
        }

        public String getTmxxBl() {
            return tmxxBl;
        }

        public void setTmxxBl(String tmxxBl) {
            this.tmxxBl = tmxxBl;
        }
    }

    /**
     * 问卷填写-题目选项统计（导出）
     */
    public void exportWjStat(String fwjjbxxid, HttpServletResponse response){
        // 总提交数
        Integer total = spcyWjWjjbxxMapper.findWjSubmitCount(fwjjbxxid);

        List<WjtmStatBo> dataList = new ArrayList<>();

        // 问卷大标题
        List<String> wjDbtList = spcyWjWjjbxxMapper.findWjDbtList(fwjjbxxid);

        // 所有题目
        List<SpcyWjWjtm> orTmList = spcyWjWjtmService.list(new LambdaQueryWrapper<SpcyWjWjtm>()
                .eq(SpcyWjWjtm::getFwjjbxxid, fwjjbxxid)
                .orderByAsc(SpcyWjWjtm::getFxh));

        for (String wjdbt : wjDbtList) {

            List<SpcyWjWjtm> tmList = orTmList.stream()
                    .filter(f -> StringUtils.isNotBlank(f.getFwjtmdbt()) && f.getFwjtmdbt().equals(wjdbt))
                    .collect(Collectors.toList());

            for (SpcyWjWjtm tm : tmList) {

                // 所有题目选项
                List<String> wjtmxxList = spcyWjWjjbxxMapper.findWjtmxxList(tm.getId());

                // 对应题目-所以选中的选项
                List<String> selectedTmxxList = spcyWjWjjbxxMapper.findSelectedOption(fwjjbxxid, tm.getFwjtm(), PxSjConstant.WJTM_XX_SFXZ_YES);

                for (String xx : wjtmxxList) {
                    WjtmStatBo statBo = new WjtmStatBo();
                    statBo.setTm(tm.getFwjtm());
                    statBo.setTmxx(xx);

                    int size = 0;
                    if (CollectionUtil.isNotEmpty(selectedTmxxList)) {
                        size = selectedTmxxList.stream()
                                .filter(str -> StringUtils.isNotBlank(str) && str.equals(xx))
                                .collect(Collectors.toList())
                                .size();
                    }
                    statBo.setTmxxSize(size);
                    statBo.setTmxxBl(StringPatternUtils.CalculatePpercentage(size, total) + "%");

                    dataList.add(statBo);
                }

                // 题目是否配置填写-意见
                if (StringUtils.isNotBlank(tm.getFsftxyjjy()) && tm.getFsftxyjjy().equals("是")){
                    StringBuffer tmyj = new StringBuffer();

                    WjtmStatBo statBo = new WjtmStatBo();
                    statBo.setTm(tm.getFwjtm());

                    // 已填写的意见
                    List<String> wjtmTxyjList = spcyWjWjjbxxMapper.findWjtmTxyj(fwjjbxxid, tm.getFwjtm());
                    int order = 0;
                    for (String yj : wjtmTxyjList){
                        if (StringUtils.isBlank(yj)){
                            continue;
                        }
                        if (!StringPatternUtils.verifryIsEmptyStringBuffer(tmyj)){
                            tmyj.append("\n");
                        }
                        tmyj.append( (order + 1) + ". ").append(yj);
                        order++;
                    }

                    statBo.setTmxx("(其他/意见)：\n" + tmyj);
                    statBo.setTmxxSize(order);
                    statBo.setTmxxBl(StringPatternUtils.CalculatePpercentage(order, total) + "%");

                    dataList.add(statBo);
                }

            }

        }

        exportWjStatUtil(spcyWjWjjbxxMapper.findWjTitle(fwjjbxxid),
                "问卷统计",
                dataList,
                4,
                response);
    }

    /**
     * 导出问卷填写-题目选项统计
     * @param dataList 导出数据列表
     * @param fileName 导出问卷名称(无后缀.xls)
     * @param colSize 列表数量
     * @param sheetName 表格簿名称
     * */
    private void exportWjStatUtil(String sheetName, String fileName, List<WjtmStatBo> dataList, int colSize, HttpServletResponse response){

        // 创建Excel工作簿和工作表
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet(sheetName);

        // 初始化行索引和前一行的科室、绩效指标类型
        int rowNum = 1;

        // 设置列宽
        for (int i = 0; i < colSize; i++) {
            // 除了第一行不设置宽度
            sheet.setColumnWidth(i, 25 * 256);
        }

        // 标题样式
        CellStyle titleStyle = workbook.createCellStyle();
        titleStyle.setBorderBottom(BorderStyle.THIN); // 下边框
        titleStyle.setBorderLeft(BorderStyle.THIN); // 左边框
        titleStyle.setBorderTop(BorderStyle.THIN); // 上边框
        titleStyle.setBorderRight(BorderStyle.THIN); // 右边框
        titleStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中

        // 标题字体
        Font titleFont = workbook.createFont();
        titleFont.setFontName("宋体");
        titleFont.setBold(true);
        titleFont.setFontHeightInPoints((short) 12);
        titleStyle.setFont(titleFont); // 选择需要用到的字体格式

        // 内容居中样式
        CellStyle centerStyle = workbook.createCellStyle();
        centerStyle.setBorderBottom(BorderStyle.THIN); // 下边框
        centerStyle.setBorderLeft(BorderStyle.THIN); // 左边框
        centerStyle.setBorderTop(BorderStyle.THIN); // 上边框
        centerStyle.setBorderRight(BorderStyle.THIN); // 右边框
        centerStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
        centerStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中

        // 内容字体
        Font centerFont = workbook.createFont();
        centerFont.setFontName("宋体");
        centerFont.setFontHeightInPoints((short) 12);
        centerStyle.setFont(centerFont); // 选择需要用到的字体格式

        // 创建CellStyle并启用自动换行
        CellStyle wrapTextStyle = workbook.createCellStyle();
        wrapTextStyle.setWrapText(true);
        wrapTextStyle.setBorderBottom(BorderStyle.THIN); // 下边框
        wrapTextStyle.setBorderLeft(BorderStyle.THIN); // 左边框
        wrapTextStyle.setBorderTop(BorderStyle.THIN); // 上边框
        wrapTextStyle.setBorderRight(BorderStyle.THIN); // 右边框
        wrapTextStyle.setFont(centerFont);

        // 自动换行居住
        CellStyle wrapTextCenterStyle = workbook.createCellStyle();
        wrapTextCenterStyle.setWrapText(true);
        wrapTextCenterStyle.setBorderBottom(BorderStyle.THIN); // 下边框
        wrapTextCenterStyle.setBorderLeft(BorderStyle.THIN); // 左边框
        wrapTextCenterStyle.setBorderTop(BorderStyle.THIN); // 上边框
        wrapTextCenterStyle.setBorderRight(BorderStyle.THIN); // 右边框
        wrapTextCenterStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
        wrapTextCenterStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
        wrapTextCenterStyle.setFont(centerFont);

        // 表头
        List<String> titleList = CollectionUtil.newArrayList(
                "问卷题目",
                "选项",
                "统计",
                "总人数和各选项的占比"
        );
        /** 创建标题行 */
        Row row1 = sheet.createRow(0);
        for (int i = 0; i < titleList.size(); i++){
            Cell cell = row1.createCell(i);
            cell.setCellValue(titleList.get(i));
            cell.setCellStyle(titleStyle);
        }

        int d1 = 1;
//        int d2 = 1;

        List<Map> merList = new ArrayList<>();
        Map<String, String> merMap = null;
        for (WjtmStatBo record : dataList) {
            Row row = sheet.createRow(rowNum++);

            // 填充单元格数据
            Cell cell0 = row.createCell(0);
            cell0.setCellValue(record.getTm());
            cell0.setCellStyle(wrapTextCenterStyle);

            Cell cell1 = row.createCell(1);
            cell1.setCellValue(record.getTmxx());
            cell1.setCellStyle(wrapTextStyle);

            Cell cell2 = row.createCell(2);
            cell2.setCellValue(record.getTmxxSize());
            cell2.setCellStyle(centerStyle);

            Cell cell3 = row.createCell(3);
            cell3.setCellValue(record.getTmxxBl());
            cell3.setCellStyle(centerStyle);


            // 检查是否需要合并单元格
            if ( (rowNum-1) < dataList.size()) {
                if (dataList.get(rowNum-2).getTm().equals(dataList.get(rowNum-1).getTm())) {
                    d1++;
                } else {
                    merMap = new HashMap<>();
                    merMap.put("c1", (d1 + ":" + (rowNum - d1) + ":" + (rowNum - 1)));
                    d1 = 1;
                    merList.add(merMap);
                }

                /*if (dataList.get(rowNum-2).getTmyj().equals(dataList.get(rowNum-1).getTmyj())) {
                    d2++;
                } else {
                    merMap = new HashMap<>();
                    merMap.put("c2", (d2 + ":" + (rowNum - d2) + ":" + (rowNum - 1)));
                    d2 = 1;
                    merList.add(merMap);
                }*/
            }else {
                merMap = new HashMap<>();
                merMap.put("c1", (d1 + ":" + (rowNum - d1) + ":" + (rowNum - 1)));
                d1 = 1;
                merList.add(merMap);

                /*merMap = new HashMap<>();
                merMap.put("c2", (d2 + ":" + (rowNum - d2) + ":" + (rowNum - 1)));
                d2 = 1;
                merList.add(merMap);*/
            }
        }

        for (Map<String,String> map : merList) {
            for (Map.Entry<String, String> merData : map.entrySet()) {
                String[] split = merData.getValue().split(":");
                Integer index = Integer.valueOf(split[0]);
                if (merData.getKey().equals("c1") && index > 1) {
                    sheet.addMergedRegion(new CellRangeAddress(
                            Integer.valueOf(split[1]), Integer.valueOf(split[2]), // 合并从mergeStartRow到最后一行的区域
                            0, 0// 只合并所在的列
                    ));
                }

                /*if (merData.getKey().equals("c2") && index > 1) {
                    sheet.addMergedRegion(new CellRangeAddress(
                            Integer.valueOf(split[1]), Integer.valueOf(split[2]), // 合并从mergeStartRow到最后一行的区域
                            1, 1// 只合并所在的列
                    ));
                }*/
            }
        }


        // 写入文件
        try {
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            //前端存在跨域不成功，设置可访问
            response.setHeader("Access-Control-Allow-Origin","*");
            //设置不要缓存
            response.setHeader("Pragma", "No-cache");
            // 这里URLEncoder.encode可以防止中文乱码
            try {
                fileName = URLEncoder.encode(fileName, String.valueOf(StandardCharsets.UTF_8));
            }catch (Exception e){
                fileName = "问卷统计";
            }
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");

            OutputStream outStream = response.getOutputStream();
            workbook.write(outStream);
            //关闭流
            outStream.flush();
            outStream.close();
            workbook.close();

        } catch (IOException e) {
            log.error("问卷统计导出异常：{}", e.getMessage());
        }
    }

}
